<?php
/**
 * Created by PhpStorm.
 * User: Administratorjing
 * Date: 2018/6/6/006
 * Time: 17:42
 */

namespace app\api\service;

use app\api\model\Order as OrderModel;
use app\api\service\Order as OrderService;
use app\lib\enum\OrderStatusEnum;
use app\lib\exception\OrderException;
use app\lib\exception\TokenException;
use think\Exception;
use think\Loader;
use think\Log;

//引入文件extend/WxPay/WxPay.Api.php
Loader::import('WxPay.WxPay','EXTEND_PATH','.Api.php');

class Pay
{
    private $orderID;
    private $orderNo;
    function __construct($orderID)
    {
        if(!$orderID)
        {
            throw new Exception('订单号不允许为null');
        }
        $this->orderID = $orderID;
    }
    public function pay()
    {
//        订单号不存在
//        订单号存在，但订单号和当前用户是不匹配的
//        订单号可能已经被支付
//        库存量检测
        $this->checkOrderValid();//新进行检测
        $orderService = new OrderService();
        $status = $orderService->checkOrderStock($this->orderID);
        if(!$status['pass']){
            return $status;
        }
        //库存量通过之后
        return $this->makeWxPreOrder($status['orderPrice']);
    }
    //调用微信支付预订单的接口
    private function makeWxPreOrder($totalPrice)
    {
        //获取openid
        $openid = Token::getCurrentTokenVar('openid');
        if(!$openid)
        {
            throw new TokenException();
        }
        //实例化Wxapi
        $wxOrderData = new \WxPayUnifiedOrder();
        //赋值
        $wxOrderData->SetOut_trade_no($this->orderNo);
        $wxOrderData->SetTrade_type('JSAPI');
        $wxOrderData->SetTotal_fee($totalPrice*100);
        $wxOrderData->SetBody('一街美食');
        $wxOrderData->SetOpenid($openid);
        //接收微信回调地址
        $wxOrderData->SetNotify_url(config('secure.pay_back_url'));
        //调用接口
        return $this->getPaySignature($wxOrderData);
    }
    private function getPaySignature($wxOrderData)
    {
        $wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
        if($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] != 'SUCCESS')
        {
            Log::record($wxOrder,'error');
            Log::record('获取预订单失败','error');
        }
        //使用prepay_id，调用下面的方法
        $this->recordPreOrder($wxOrder);
        //调用标签
        $signature = $this->sign($wxOrder);
        return $signature;
    }
    //弄签名
    private function sign($wxOrder)
    {
        $jsApiPayData = new \WxPayApi();
        $jsApiPayData->SetAppid(config('wx.app_id'));
        $jsApiPayData->SetTimeStamp((string)time());
        $rand = md5(time().mt_rand(0,1000));
        $jsApiPayData-> SetNonceStr($rand);
        $jsApiPayData->SetPackage('prepay_id='.$wxOrder['prepay_id']);
        $jsApiPayData->SetSignType('md5');
        $sign = $jsApiPayData->MakeSign();
        $rawValues = $jsApiPayData->GetValues();
        $rawValues['paySign'] = $sign;
        unset($rawValues['appId']);
        return $rawValues;
    }
    //处理prepay_id
    private function recordPreOrder($wxOrder)
    {
        //保存到数据库里面
        OrderModel::where('id','=',$this->orderID)->update(['prepay_id'=>$wxOrder['prepay_id']]);
    }

    private function checkOrderValid()
    {
        $order = OrderModel::where('id','=',$this->orderID)->find();
        if(!$order)
        {
            throw new OrderException();
        }
        //如果订单不匹配
        if(!Token::isValidOperate($order->user_id)){
            throw new TokenException([
               'msg' => '订单与用户不匹配',
               'errorCode' => 10003
            ]);
        }
        //1代表待支付、
        if($order->status != OrderStatusEnum::UNPAID)
        {
            throw new OrderException([
                'msg' => '订单已经支付啦O(∩_∩)O~~',
                'errorCode' => 80003,
                'code' => 400
            ]);
            $this->orderNo = $order->order_no;
            return true;
        }
    }
}